10.4 Ein Beispiel
 
An einem abschließenden Beispiel soll skizziert werden, wie sich das Zusammenspiel zwischen VB.NET und XML organisieren lässt und wie man dies in der Praxis verwenden könnte. Erinnern Sie sich an Kapitel 5? Dort wurden Informationen, die der Benutzer eingegeben hatte, nach Excel geschrieben. Nun sollen diese Daten, die sich in der Liste befinden, angezeigt werden (damit der Benutzer sie noch ändern kann). Danach steht ihm die Möglichkeit zur Verfügung, diese Daten in ein XML-Dokument zu schreiben, das mit einer XSL-Datei verknüpft ist, damit es im Internet (oder Intranet) angezeigt werden kann.
10.4.1 Das TreeView-Steuerelement
 
Da das Denken in baumartigen Strukturen nun bekannt ist, stellt das bislang noch nicht besprochene Treeview-Steuerelement sicherlich keine große Schwierigkeit dar. Es wird auf ein Formular gesetzt und erhält den Namen »trvBaum«. Es besitzt folgende wichtige Eigenschaften:
Tabelle 10.11
Die wichtigsten Eigenschaften des TreeView-Steuerelements
| Eigenschaft
|
Beschreibung
|
| CheckBoxes
|
setzt oder überprüft, ob neben den Einträgen Kästchen zu sehen sind, mit denen die Einträge geöffnet und geschlossen werden können
|
| ShowLines, ShowPlusMinus, ShowRootLines
|
setzt oder überprüft die Linien, das +/--Symbol und die Linie des Wurzelelements
|
| LabelEdit
|
0 - tvwLabelAutomatic oder1 - tvwLabelManual bestimmt, ob die Beschriftung mit einem zweiten Klick auf einen Knoten geändert werden kann (tvwLabelAutomatic)
|
| Indent
|
Einrückung der einzelnen Ebenen
|
| Sorted
|
legt fest, ob die Knoten der obersten Ebene sortiert sind
|
| PathSeparator
|
das Trennzeichen, das für die Path-Eigenschaft verwendet wird
|
| Appearance
|
0 - ccFlat1 - cc3 bestimmt das Aussehen des TreeView-Steuerelements
|
Per VB.NET stehen Ihnen für das Steuerelement weitere Eigenschaften zur Verfügung:
Tabelle 10.12
Die wichtigsten Eigenschaften des TreeView-Steuerelements in VBA
| Eigenschaft
|
Beschreibung
|
| DataBindings
|
legt die Verbindung zu einer Datenquelle fest
|
| Nodes
|
die Nodes-Sammlung
|
| SelectedNode
|
der zurzeit ausgewählte Knoten
|
Das Objekt Node (beispielsweise »SelectedNode«) stellt einen Knoten dar, der wiederum einige Eigenschaften und Methoden besitzt:
Tabelle 10.13
Die wichtigsten Eigenschaften eines Knotens
| Eigenschaft
|
Beschreibung
|
| Text
|
der angezeigte Text des Knotens
|
| FullPath
|
der gesamte Pfad des Knotens
|
| IsExpanded
|
gibt an, ob der Knoten zurzeit geöffnet (»True«) ist oder nicht
|
| IsSelected
|
gibt an, ob der Knoten markiert ist (»True«)
|
| IsEditing
|
kann bearbeitet werden
|
| Parent
|
der Elternknoten
|
| Child
|
der erste Kindknoten
|
| FirstNode
|
der erste Geschwisterknoten
|
| LastNode
|
der letzte Geschwisterknoten
|
| NextNode
|
der nächste Geschwisterknoten
|
| PrevNode
|
der vorangehende Geschwisterknoten
|
| Nodes
|
die Kindknoten
|
| Checkes
|
aktiviert Strukturknoten
|
| Index
|
die Nummer des Knotens
|
Neben den Eigenschaften existieren noch einige Methoden des TreeView-Steuerelements. Hier eine kleine Auswahl:
Tabelle 10.14
Die wichtigsten Methoden des TreeView
| Methode
|
Beschreibung
|
| GetNodeCount
|
die Anzahl der sichtbaren Knoten
|
| CollapseAll
|
reduziert alle Strukturknoten
|
| ExpandAll
|
erweitert alle Strukturknoten
|
| Refresh
|
aktualisiert das Steuerelement
|
| Focus, Select
|
setzt den Fokus auf das Steuerelement
|
Während ein einzelner Knoten über keine bedeutenden Methode verfügt, besitzt die Sammlung Nodes die vier wichtigen Methoden »Add«, »Insert«, »Clear« und »Remove«. Das Steuerelement verfügt weiter über die Ereignisse »BeforeLabelEdit« und »AfterLabelEdit«, »Click« und »NodeClick« (wenn ein Knoten angeklickt wird), »Expand« und »Collapse« (wenn ein Knoten geöffnet und geschlossen wird). Damit ist nun das Fundament gelegt, um ein solches Steuerelement zu füllen. Soll beispielsweise beim Markieren eines Knotens der Text angezeigt werden, dann kann die Eigenschaft
Me.tvwBaum.SelectedNode.Text
verwendet werden. Die Position wird mit Index ermittelt. So könnte man sich die Position und den Namen des »Chefknotens« anzeigen lassen:
Private Sub tvwBaum_AfterSelect(ByVal sender As Object, _
ByVal e As System.Windows.Forms.TreeViewEventArgs) _
Handles tvwBaum.AfterSelect
If Me.tvwBaum.SelectedNode.FullPath.IndexOf("\") = -1 Then
MessageBox.Show("pos." & _
(Me.tvwBaum.SelectedNode.Index + 1).ToString & _
": " & Me.tvwBaum.SelectedNode.Text )
Else
MessageBox.Show("pos." & _
(Me.tvwBaum.SelectedNode.Parent.Index() + 1).ToString & _
": " & Me.tvwBaum.SelectedNode.Parent.Text & vbCr & _
Me.tvwBaum.SelectedNode.Text)
End If
End Sub
Auf einer Userform wird eine Test-Schaltfläche angebracht. Sie soll das Steuerelement (tvwBaum) lediglich mit einem Text füllen:
Dim i As Integer
Dim j As Integer
Dim tvwKnoten As TreeNode
Me.tvwBaum.Nodes.Clear()
With tvwBaum
.CheckBoxes = False
.ShowLines = True
.ShowPlusMinus = True
.ShowRootLines = True
End With
For i = 1 To 3
tvwKnoten = Me.tvwBaum.Nodes.Add("Kapitel" & i.ToString)
For j = 1 To 5
tvwKnoten.Nodes.Add("Unterkapitel" & j.ToString)
Next j
Next i
Me.tvwBaum.Select()
Me.tvwBaum.SelectedNode = Me.tvwBaum.Nodes(0)
Abbildung 10.39
Im TreeView-Steuerelement werden drei Knoten mit jeweils fünf Kindknoten erzeugt.
Zu Beginn werden einige der Eigenschaften des Steuerelements festgelegt. Danach zählen zwei Zählervariablen (i und j) von 1 bis 3 beziehungsweise 5 hoch. Die Methode Add erzeugt einen neuen Knoten. Der Text wird angezeigt. Wollte man mit diesen Knoten weiterarbeiten, könnte man deklarieren
Dim tvwUnterknoten As Node
und schließlich die Add-Methode anwenden.
10.4.2 Daten werden eingelesen
 
Und mit diesen Befehlen ist es nun leicht möglich, eine XML-Datei dynamisch zu halten. Eine weitere Schaltfläche (»butOK«) oder das Ereignis »Load« füllt das Steuerelement. Das Markieren eines beliebigen Eintrags zeigt die dazu gespeicherten Daten in mehreren Textfeldern an. Im folgenden Beispiel werden aus der Excel-Liste die drei Informationen »Name«, »Betrag« und »Datum« ausgelesen, wobei die letzten beiden einen Knoten von »Name« darstellen:
xlApp = New Excel.Application()
xlApp.Visible = False
If System.IO.File.Exists(strExcelDateiname) Then
Me.StatusBar1.Text = "Achtung: Datenimport läuft."
Me.Cursor = Cursors.WaitCursor
xlMappe = xlApp.Workbooks.Open(strExcelDateiname)
xlBlatt = xlMappe.Worksheets(1)
xlZelle = xlBlatt.Range("A1")
intZeilen = xlZelle.CurrentRegion.Rows.Count
Me.tvwBaum.Nodes.Clear()
For intZähler = 1 To intZeilen - 1
tvwKnoten = _
Me.tvwBaum.Nodes.Add(xlZelle.Offset(intZähler, _
2).Value)
strText = CType(xlZelle.Offset(intZähler, 1).Value, _
String)
tvwKnoten.Nodes.Add(strText)
strText = Format(xlZelle.Offset(intZähler, _
3).Value, "0.00")
tvwKnoten.Nodes.Add(strText)
Next
xlMappe.Close()
xlApp.Quit()
xlZelle = Nothing
xlBlatt = Nothing
xlMappe = Nothing
xlApp = Nothing
End If
Me.StatusBar1.Text = ""
Me.Cursor = Cursors.Default
Me.ProgressBar1.Value = 0
Abbildung 10.40
Die Daten werden ausgelesen und als Baum dargestellt.
Die Aufgabe war, dass der Benutzer die Texte ändern können soll. Man kann sie direkt im TreeView ändern lassen. Ebenso könnte man sie in eigens dafür vorbereiteten Textfeldern editieren oder in ein Dataset laden, die Verbindung zu Excel bereitstellen oder in ein Array laden. Letzteres wird gemacht. Das zweidimensionale Datenfeld strKunde() nimmt die Inhalte auf:
Me.tvwBaum.Nodes.Clear()
For intZähler = 1 To intZeilen - 1
strKunde(0, intZähler - 1) = _
xlZelle.Offset(intZähler, 2).Value
strKunde(1, intZähler - 1) = _
CType(xlZelle.Offset(intZähler, 1).Value, String)
strKunde(2, intZähler - 1) = _
Format(xlZelle.Offset(intZähler, 3).Value, "0.00") _
& " Euro"
tvwKnoten = _
Me.tvwBaum.Nodes.Add(strKunde(0, intZähler - 1))
tvwKnoten.Nodes.Add(strKunde(1, intZähler - 1))
tvwKnoten.Nodes.Add(strKunde(2, intZähler - 1))
Next
Me.tvwBaum.Select()
Me.tvwBaum.SelectedNode = Me.tvwBaum.Nodes(0)
Und schließlich muss noch festgelegt werden, dass beim Ändern der Liste die korrekten Daten in den Textfeldern stehen:
Private Sub tvwBaum_AfterSelect(ByVal sender As Object, _
ByVal e As System.Windows.Forms.TreeViewEventArgs) _
Handles tvwBaum.AfterSelect
If Me.tvwBaum.SelectedNode.FullPath.IndexOf("\") = -1 Then
Me.txtName.Text = strKunde(0, _
Me.tvwBaum.SelectedNode.Index)
Me.txtDatum.Text = strKunde(1, _
Me.tvwBaum.SelectedNode.Index)
Me.txtGeld.Text = strKunde(2, _
Me.tvwBaum.SelectedNode.Index)
Else
Me.txtName.Text = strKunde(0, _
Me.tvwBaum.SelectedNode.Parent.Index)
Me.txtDatum.Text = strKunde(1, _
Me.tvwBaum.SelectedNode.Parent.Index)
Me.txtGeld.Text = strKunde(2, _
Me.tvwBaum.SelectedNode.Parent.Index)
End If
End Sub
Abbildung 10.41
Die Daten werden auch in den Textfeldern angezeigt.
Und nun könnten sie analog in das Datenfeld und das TreeView zurück geschrieben werden. Diese Variante ist sicherlich komplizierter als das Arbeiten mit einem Dataset. Ich möchte das Editieren im TreeView erlauben.
Abbildung 10.42
Aus Robert wird Marta, und sie zahlt mit Kronen.
10.4.3 Export in eine XML-Datei
 
Die nun geänderten Daten werden in eine XML-Datei geschrieben:
Dim x0 As New Xml.XmlDocument()
Dim xDekl As Xml.XmlDeclaration
Dim xWurzel As Xml.XmlElement
Dim x1 As Xml.XmlElement
Dim x2 As Xml.XmlElement
Dim x3 As Xml.XmlText
xDekl = x0.CreateXmlDeclaration("1.0", "ISO-8859-1", "yes")
x0.AppendChild(xDekl)
xWurzel = x0.CreateElement("Liste")
x0.AppendChild(xWurzel)
For Each tvwKnoten In tvwBaum.Nodes
x1 = x0.CreateElement("Kunde")
x2 = x0.CreateElement("Name")
x3 = x0.CreateTextNode(tvwKnoten.Text)
x2.AppendChild(x3)
x1.AppendChild(x2)
x2 = x0.CreateElement("Datum")
x3 = x0.CreateTextNode(tvwKnoten.Nodes(0).Text)
x2.AppendChild(x3)
x1.AppendChild(x2)
x2 = x0.CreateElement("Betrag")
x3 = x0.CreateTextNode(tvwKnoten.Nodes(1).Text)
x2.AppendChild(x3)
x1.AppendChild(x2)
xWurzel.AppendChild(x1)
Next
x0.Save(strExcelDateiname.Substring(0, strExcelDateiname.Length - 4) & ".xml")
Me.Close()
Bei Schleifen oder bei sehr vielen Elementen empfiehlt sich natürlich der Durchlauf mit einer Schleife oder rekursiver Programmierung. Da in unserem Beispiel die Anzahl der Kindelemente und die Tiefe bekannt sind, habe ich darauf verzichtet (siehe Abbildung 10.43).
Abbildung 10.43
Das Ergebnis des Exports
Und schließlich wird noch eine XSL-Datei programmiert:
x0 = New Xml.XmlDocument()
xWurzel = x0.CreateElement("stylesheet", "xsl")
xWurzel.SetAttribute("xmlns:xsl", _
"http://www.w3.org/TR/WD-xsl")
x0.AppendChild(xWurzel)
x1 = x0.CreateElement("template", "xsl")
x0.DocumentElement.AppendChild(x1)
x2 = x0.CreateElement("STYLE", "HTML")
x1.AppendChild(x2)
xCDATA = x0.CreateCDataSection(".Tabellenkopf" & _
"{ align:center; color:red; font-family:Arial; " & _
"font-size:14pt; Font -Weight: Bold } " & _
".Tabellengestaltung { color:black; " & _
"font-family:Times; font-size:10pt }")
x2.AppendChild(xCDATA)
x4 = x0.CreateElement("TABLE", "HTML")
x4.SetAttribute("BORDER", "3")
x4.SetAttribute("WIDTH", "100 %")
x4.SetAttribute("ALIGN", "center")
x4.SetAttribute("CLASS", "Tabellenkopf")
x1.AppendChild(x4)
x5 = x0.CreateElement("TR", "HTML")
x4.AppendChild(x5)
x6 = x0.CreateElement("TD", "HTML")
x5.AppendChild(x6)
x7 = x0.CreateElement("DIV", "HTML")
x3 = x0.CreateTextNode("Name")
x7.AppendChild(x3)
x6.AppendChild(x7)
x6 = x0.CreateElement("TD", "HTML")
x5.AppendChild(x6)
x7 = x0.CreateElement("DIV", "HTML")
x3 = x0.CreateTextNode("Datum")
x7.AppendChild(x3)
x6.AppendChild(x7)
x6 = x0.CreateElement("TD", "HTML")
x5.AppendChild(x6)
x7 = x0.CreateElement("DIV", "HTML")
x3 = x0.CreateTextNode("Betrag")
x7.AppendChild(x3)
x6.AppendChild(x7)
x5 = x0.CreateElement("for-each", "xsl")
x5.SetAttribute("xsl:select", "Liste/Kunde")
x4.AppendChild(x5)
x6 = x0.CreateElement("TR", "HTML")
x6.SetAttribute("CLASS", "Tabellengestaltung")
x5.AppendChild(x6)
x7 = x0.CreateElement("TD", "HTML")
x6.AppendChild(x7)
x8 = x0.CreateElement("DIV", "HTML")
x7.AppendChild(x8)
x9 = x0.CreateElement("value-of", "xsl")
x9.SetAttribute("xsl:select", "Name")
x8.AppendChild(x9)
x7 = x0.CreateElement("TD", "HTML")
x6.AppendChild(x7)
x9 = x0.CreateElement("value-of", "xsl")
x9.SetAttribute("xsl:select", "Datum")
x8 = x0.CreateElement("DIV", "HTML")
x7.AppendChild(x8)
x8.AppendChild(x9)
x7 = x0.CreateElement("TD", "HTML")
x6.AppendChild(x7)
x9 = x0.CreateElement("value-of", "xsl")
x9.SetAttribute("xsl:select", "Betrag")
x8 = x0.CreateElement("DIV", "HTML")
x7.AppendChild(x8)
x8.AppendChild(x9)
x0.Save(strExcelDateiname.Substring(0, strExcelDateiname.Length - 4) & ".xsl")
Me.Close()
Daraus ergibt sich die XSL-Datei:
Abbildung 10.44
Das Resultat des Exports
Die XML-Datei muss natürlich mit dieser verknüpft werden:
xProz = x0.CreateProcessingInstruction("xml-stylesheet", _
"href=""Statistik.xsl"" type=""text/xsl""")
x0.AppendChild(xDekl) : Call Weiter()
x0.AppendChild(xProz)
Und dann kann die Ausgabe im Browser erfolgen:
Abbildung 10.45
Die XML-Datei wurde mit der XSL-Datei verknüpft.
|